Guild icon
Project Sekai
🔒 UMDCTF 2023 / ✅-mobile-flamecamp
Avatar
Flamecamp - 500 points
Category: Mobile Description: Flamecamp is a new social media app exclusive to Fire type Pokemon. Can you get access to it? Author: matlac Files:Tags: No tags.
Sutx pinned a message to this channel. 04/28/2023 3:01 PM
Avatar
@Violin wants to collaborate 🤝
Avatar
@joezid wants to collaborate 🤝
19:39
@Iyed wants to collaborate 🤝
Avatar
@fleming wants to collaborate 🤝
Avatar
it should be an easy challenge we have <string name="google_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_app_id">1:1090871602799:android:c1d198201cd7635db5279a</string> <string name="google_crash_reporting_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_storage_bucket">flamecamp.appspot.com</string>
20:45
and when we sign in the app will download a jpg file from the bucket
20:45
StorageReference storageRef = FirebaseStorage.getInstance().getReference().child("flamecamp_welcome.jpg"); Intrinsics.checkNotNullExpressionValue(storageRef, "getInstance().reference.…(\"flamecamp_welcome.jpg\")"); File localFile = File.createTempFile("temp", "jpg"); FileDownloadTask file = storageRef.getFile(localFile);
Avatar
whats the goal?
Avatar
i think i still didnt understand
Avatar
We have to signin to make the apk download the image to get the flag
Avatar
where's the image downloaded from?
Avatar
Tried multiple stuff to directly download the image but no luck
22:43
gs:://bucket/flamecamp_welcome.jpg
Avatar
Avatar
joezid
it should be an easy challenge we have <string name="google_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_app_id">1:1090871602799:android:c1d198201cd7635db5279a</string> <string name="google_crash_reporting_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_storage_bucket">flamecamp.appspot.com</string>
Buck url is here
Avatar
@Legoclones wants to collaborate 🤝
Avatar
is anything missing to get file?
Avatar
that looks like it lemme see
22:48
nvm
Avatar
@IceCreamMan wants to collaborate 🤝
Avatar
There's no authentication taking place here, right?
Avatar
not sure
23:02
i think there's auth
23:03
public final void signIn(View v) { Intrinsics.checkNotNullParameter(v, "v"); setEmailString(getEmailInput().getText().toString()); setPasswordString(getPasswordInput().getText().toString()); if (!Intrinsics.areEqual(getEmailString(), "") && !Intrinsics.areEqual(getPasswordString(), "")) { FirebaseAuth firebaseAuth = this.auth; if (firebaseAuth == null) { Intrinsics.throwUninitializedPropertyAccessException("auth"); firebaseAuth = null; } firebaseAuth.signInWithEmailAndPassword(getEmailString(), getPasswordString()).addOnCompleteListener(this, new OnCompleteListener() { // from class: com.example.flamecamp.MainActivity$$ExternalSyntheticLambda1 @Override // com.google.android.gms.tasks.OnCompleteListener public final void onComplete(Task task) { MainActivity.signIn$lambda$1(MainActivity.this, task); } }); return; } getErrorIndicator().setText("@string/signInError"); }
23:03
/* JADX INFO: Access modifiers changed from: private */ public static final void signIn$lambda$1(MainActivity this$0, Task task) { Intrinsics.checkNotNullParameter(this$0, "this$0"); Intrinsics.checkNotNullParameter(task, "task"); if (task.isSuccessful()) { this$0.setContentView(R.layout.post_auth); StorageReference storageRef = FirebaseStorage.getInstance().getReference().child("flamecamp_welcome.jpg"); Intrinsics.checkNotNullExpressionValue(storageRef, "getInstance().reference.…(\"flamecamp_welcome.jpg\")"); File localFile = File.createTempFile("temp", "jpg"); FileDownloadTask file = storageRef.getFile(localFile); final MainActivity$signIn$1$1 mainActivity$signIn$1$1 = new MainActivity$signIn$1$1(localFile, this$0); file.addOnSuccessListener(new OnSuccessListener() { // from class: com.example.flamecamp.MainActivity$$ExternalSyntheticLambda0 @Override // com.google.android.gms.tasks.OnSuccessListener public final void onSuccess(Object obj) { MainActivity.signIn$lambda$1$lambda$0(Function1.this, obj); } }); return; } this$0.getErrorIndicator().setText("@string/signInError"); }
23:03
like you will get @string/signInError if wrong
23:04
its confusing because we dont know the email/password (unless its in some string)
23:04
if we bypass login not sure if we can directly read the bucket file
Avatar
Avatar
sahuang
if we bypass login not sure if we can directly read the bucket file
hmm feels like the authentication is done on firebase side, instead of in the apk (edited)
Avatar
yeah i think so, but how do we know the creds
23:10
actually we should just get file instead of cred
23:10
unless file is only accessible to those who auth
Avatar
how did you decompile apk?
23:16
what tool?
Avatar
jadx-gui
Avatar
Avatar
IceCreamMan
hmm feels like the authentication is done on firebase side, instead of in the apk (edited)
im pretty sure we can just get file without auth right
Avatar
Idk, that's been the issue I've been running into
Avatar
from the code, we can remove task.isSuccessful if possible
Avatar
it looks for auth
Avatar
if (task.isSuccessful()) { this$0.setContentView(R.layout.post_auth); StorageReference storageRef = FirebaseStorage.getInstance().getReference().child("flamecamp_welcome.jpg"); Intrinsics.checkNotNullExpressionValue(storageRef, "getInstance().reference.…(\"flamecamp_welcome.jpg\")"); File localFile = File.createTempFile("temp", "jpg"); FileDownloadTask file = storageRef.getFile(localFile); final MainActivity$signIn$1$1 mainActivity$signIn$1$1 = new MainActivity$signIn$1$1(localFile, this$0); file.addOnSuccessListener(new OnSuccessListener() { // from class: com.example.flamecamp.MainActivity$$ExternalSyntheticLambda0 @Override // com.google.android.gms.tasks.OnSuccessListener public final void onSuccess(Object obj) { MainActivity.signIn$lambda$1$lambda$0(Function1.this, obj); } }); return; }
23:18
the task is not used anywhere inside
23:21
yeah im pretty sure
23:21
the task callback is there, but its not even used when getting image
Avatar
No authentication i think
Avatar
so if somehow we can go into the if, we can get file
Avatar
But the idea is to bypass it
23:22
need change code
23:22
if (task.isSuccessful()) to if (!task.isSuccessful())
Avatar
We the api key and all the stuff used for authentication with the server but still didn’t manage to download it
23:22
Maybe missing some headers
Avatar
I tried logging in with my own Google account and got PASSWORD_LOGIN_DISABLED
23:40
When I try authenticating with the token, I get google.auth.exceptions.RefreshError: The credentials do not contain the necessary fields need to refresh the access token. You must specify refresh_token, token_uri, client_id, and client_secret.
Avatar
Avatar
joezid
it should be an easy challenge we have <string name="google_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_app_id">1:1090871602799:android:c1d198201cd7635db5279a</string> <string name="google_crash_reporting_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_storage_bucket">flamecamp.appspot.com</string>
where were these creds?
23:41
I can't find 😦
Avatar
you can basically download everything in jadx locally and string search
23:44
Avatar
There's also "messagingSenderId": "1090871602799" I found
23:49
And 1090871602799-4npel90l60lr91nl8uv7si87f4c7uhtu.apps.googleusercontent.com as default_web_client_id (edited)
Avatar
firebase remote config isn't used, I get NO_TEMPLATE returned (https://blog.deesee.xyz/android/automation/2019/08/03/firebase-remote-config-dump.html)
Avatar
yeah idk where to go from here, nothing seems to work. going to bed, see u in morning
Avatar
same, i think we need frida to bypass the step of callback, so it directly goes into the if branch
00:42
not sure if doablr
00:42
but authentication is nothing to do with getting image file
00:43
like you dont need to login to get it
Avatar
IceCreamMan 04/29/2023 3:58 AM
btw what is this doing? Intrinsics.areEqual((Object) getPasswordString(), (Object) "")
Avatar
that we haven't entered an empty string (edited)
Avatar
IceCreamMan 04/29/2023 5:05 AM
yea ok i didnt see that the app returns the same string even tho its not empty
Avatar
@jayden wants to collaborate 🤝
06:05
that one is coming from the signIn$lambda$1 method
Avatar
IceCreamMan 04/29/2023 6:17 AM
i cant hook the task.isSuccessful function with frida (edited)
Avatar
pretty sure it needs auth
06:32
trying to access it without any auth gives me a permission denied error (edited)
06:34
we have <string name="google_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_app_id">1:1090871602799:android:c1d198201cd7635db5279a</string> <string name="google_crash_reporting_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_storage_bucket">flamecamp.appspot.com</string>
06:50
pretty sure its firebase key exploit Flamecamp is a new social media app exclusive to Fire type Pokemon. Can you get access to it?
Avatar
Avatar
Violin
we have <string name="google_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_app_id">1:1090871602799:android:c1d198201cd7635db5279a</string> <string name="google_crash_reporting_api_key">AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA</string> <string name="google_storage_bucket">flamecamp.appspot.com</string>
we got this above
06:51
just no idea how to access
Avatar
@TheBadGod wants to collaborate 🤝
Avatar
seems like there is a firestore database but its in "datastore mode"
Avatar
import pyrebase config = { "apiKey": "AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA", "authDomain": "flamecamp.firebaseapp.com", "databaseURL": "https://flamecamp.firebaseio.com", "storageBucket": "flamecamp.appspot.com" } firebase = pyrebase.initialize_app(config) storage = firebase.storage() storage.child("flamecamp_welcome.jpg").download("./out.jpg") this does not throw any errors, however it does not work either
Avatar
hm, if filename is changed to some random string does it throw?
Avatar
no
Avatar
isnt it a bucket, so we need sth like bucket.get_blob
Avatar
should be handled by pyrebase
08:01
but idk
Avatar
ah self.credentials is none for some reason
Avatar
ohhhh lemme clear it
Avatar
oh credentials is only set if you have a serviceAccount
08:04
do we have that?
Avatar
No, no service account JSON file
Avatar
solved gg
Avatar
UMDCTF{W3lc0m3_t0_Th3_$ecr3t_f1r3b@se}
Avatar
Avatar
TheBadGod
import pyrebase config = { "apiKey": "AIzaSyANqtzq5t7AJ1FDJjK9if77WsV_ebvktiA", "authDomain": "flamecamp.firebaseapp.com", "databaseURL": "https://flamecamp.firebaseio.com", "storageBucket": "flamecamp.appspot.com" } firebase = pyrebase.initialize_app(config) storage = firebase.storage() storage.child("flamecamp_welcome.jpg").download("./out.jpg") this does not throw any errors, however it does not work either
use it, but pyrebase4
Avatar
Avatar
Violin
UMDCTF{W3lc0m3_t0_Th3_$ecr3t_f1r3b@se}
submit it @sahuang
Avatar
oh fuck
Avatar
they have a new version
Avatar
whats the diff
08:21
oh
Avatar
Avatar
Violin
used /ctf solve
✅ Challenge solved.
Avatar
thanks @TheBadGod thanks
Avatar
whats the image?
Avatar
Avatar
Violin
used /ctf solve
This challenge was already solved.
Avatar
seems few chars are wrong
Avatar
oh wait
08:23
08:23
correct now gg
Avatar
dang just a version difference 🤦‍♂️
Exported 118 message(s)